package logic

import (
	"context"
	"mldong/api/base"
	dictApi "mldong/api/dict"
	dao "mldong/internal/modules/sys/dao"
	"mldong/internal/modules/sys/entity"
	service "mldong/internal/modules/sys/service"
	"mldong/utility"
	"strconv"

	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/jinzhu/copier"
)

func init() {
	// 注册服务实现
	utility.Register(service.DictServiceType, NewDictLogic())
}

type DictLogic struct {
	dictDao     *dao.DictDao
	dictItemDao *dao.DictItemDao
}

// 保存字典接口实现
func (logic *DictLogic) Save(ctx context.Context, req *dictApi.SaveReq) (res bool, err error) {
	unique := utility.CheckUnique(logic.dictDao.Model(nil), "code", req.Code, nil, "唯一编码已存在，请检查code参数")
	if unique != nil {
		return false, unique
	}
	var dict = entity.Dict{}
	err = g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		req.ID = nil
		// 将req对象赋值给dict
		copier.Copy(&dict, &req)
		// 插入sys_dict表
		dict, err = logic.dictDao.Insert(dict, tx)
		if err != nil {
			return err
		}
		return nil
	})
	return dict.ID != nil, err
}

// 修改字典接口实现
func (logic *DictLogic) Update(ctx context.Context, req *dictApi.UpdateReq) (res bool, err error) {
	unique := utility.CheckUnique(logic.dictDao.Model(nil), "code", req.Code, req.ID, "唯一编码已存在，请检查code参数")
	if unique != nil {
		return false, unique
	}
	var dict = entity.Dict{}
	// 将req对象赋值给dict
	copier.Copy(&dict, &req)
	var count int64
	count, err = logic.dictDao.UpdateById(dict, nil)
	if err != nil {
		return false, err
	}
	return count > 0, err
}

// 删除字典接口实现
func (logic *DictLogic) Remove(ctx context.Context, ids []string) (res bool, _ error) {
	// 遍历ids
	// for _, id := range ids {
	// 	logic.dictDao.DeleteById(id)
	// }
	var count, err = logic.dictDao.DeleteByIds(ids)
	if err != nil {
		return false, err
	}
	if count == 0 {
		return false, err
	}
	return true, err
}

// 根据ID获取字典信息
func (logic *DictLogic) Detail(ctx context.Context, id string) (res dictApi.DictVO, err error) {
	var dictVO = dictApi.DictVO{}
	var dict entity.Dict
	dict, err = logic.dictDao.GetById(id)

	// 将dict对象赋值给dictVO
	copier.Copy(&dictVO, &dict)

	return dictVO, err
}

// 分页查询字典接口实现
func (logic *DictLogic) Page(ctx context.Context, req *dictApi.PageReq) (res dictApi.DictPageVO, err error) {
	// 处理分页参数nil值
	utility.HandlePageParam(&req.PageParam)
	dicts, total, err := logic.dictDao.Page(*req.PageNum, *req.PageSize, func(model *gdb.Model) *gdb.Model {
		return utility.BuildQuery(req.PageParam, model)
	})
	var dictVOS = []dictApi.DictVO{}
	copier.Copy(&dictVOS, &dicts)
	dictPage := dictApi.DictPageVO{
		Rows: dictVOS,
	}
	dictPage.PageNum = *req.PageNum
	dictPage.PageSize = *req.PageSize
	dictPage.RecordCount = total
	// 计算 TotalPage
	if *req.PageSize > 0 {
		dictPage.TotalPage = (total + *req.PageSize - 1) / *req.PageSize
	} else {
		dictPage.TotalPage = 0 // 如果 PageSize 为 0，则 TotalPage 为 0
	}
	return dictPage, err
}
func (logic *DictLogic) GetByDictType(ctx context.Context, dictType string) (res []base.LabelValueVO, err error) {
	res = []base.LabelValueVO{}
	results, err := logic.dictDao.Model(nil).Where("code=?", dictType).Limit(0, 1).All()
	if err != nil {
		return res, err
	}
	if results.Len() == 0 {
		// 数据库中没有，则从枚举中获取
		dictModel, dmErr := utility.FindInEnumMapModel(dictType)
		if dmErr == nil {
			return utility.DictModelToLabelValue(dictModel), nil
		}
		return res, nil
	}
	dictId := results[0].GMap().Get("id")
	dictItemResults, err := logic.dictItemDao.Model(nil).Where("dict_id=?", dictId).OrderAsc("sort").All()
	if err != nil {
		return res, err
	}
	dataType := results[0].GMap().Get("data_type").(int)
	for _, dictItemResult := range dictItemResults {
		labelValue := base.LabelValueVO{
			Label: dictItemResult.GMap().Get("name").(string),
			Ext:   g.Map{},
		}
		if dataType == 2 {
			// 当 dataType 为 2 时，Value 为 int 类型
			labelValue.Value, err = strconv.Atoi(dictItemResult.GMap().Get("code").(string))
			if err != nil {
				return res, err
			}
		} else {
			// 其他情况 Value 为 string 类型
			labelValue.Value = dictItemResult.GMap().Get("code").(string)
		}
		res = append(res, labelValue)
	}
	return res, err
}
func NewDictLogic() service.IDictService {
	return &DictLogic{
		dictDao:     dao.NewDictDao(),
		dictItemDao: dao.NewDictItemDao(),
	}
}
